package http

import (
	"crypto/md5"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/mozillazg/request"
	"github.com/toolkits/web/param"
	"joywifi.com/send-sms/config"
)

func configCommonRoutes() {
	http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("ok"))
	})

	http.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(config.VERSION))
	})
}

func configSendSmsRoutes() {
	http.HandleFunc("/sender/sms", func(w http.ResponseWriter, r *http.Request) {

		tos := param.MustString(r, "tos")
		content := param.MustString(r, "content")

		resp, err := sendSms(tos, content)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		} else {
			body, _ := ioutil.ReadAll(resp.Body)
			http.Error(w, string(body), http.StatusOK)
			//w.Write(body)
		}
	})
}

func sendSms(tos, content string) (resp *request.Response, err error) {
	cfg := config.Config()
	sid := cfg.Cloopen.Sid
	token := cfg.Cloopen.Token
	timestamp := time.Now().Format("20060102150405")

	host := cfg.Cloopen.Host + "/2013-12-26/Accounts/" + sid + "/SMS/TemplateSMS?sig="
	md5 := cryptoMd5(sid + token + timestamp)
	host = host + strings.ToUpper(md5)
	base64 := cryptoBase64(sid + ":" + timestamp)

	c := &http.Client{}
	req := request.NewRequest(c)
	req.Json = map[string]interface{}{
		"to":         tos,
		"appId":      cfg.Cloopen.Appid,
		"templateId": cfg.Cloopen.TemplateId,
		"datas":      []string{content},
	}

	jsonb, _ := json.Marshal(req.Json)

	req.Headers = map[string]string{
		"Accept-Encoding": "",
		"Content-Type":    "application/json;charset=utf-8",
		"content-length":  strconv.Itoa(len(jsonb)),
		"Accept":          "application/json",
		"Authorization":   base64,
	}

	resp, err = req.Post(host)
	return
}

func cryptoMd5(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum(nil))
}

func cryptoBase64(str string) string {
	return base64.StdEncoding.EncodeToString([]byte(str))
}
